﻿using AutoMapper;
using DFGK.WMS.Common.Web;
using DFGK_WMS.Context;
using DFGK_WMS.IRepository;
using DFGK_WMS.Model.DTO;
using DFGK_WMS.Model.Enum;
using DFGK_WMS.Model.Models;
using DFGK_WMS.Model.Models.PDA;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.IdentityModel.Logging;
using NetTaste;
using NPOI.OpenXmlFormats.Spreadsheet;
using NPOI.OpenXmlFormats.Wordprocessing;
using NPOI.POIFS.Crypt.Dsig;
using NPOI.SS.Formula.Functions;
using NPOI.SS.Formula.PTG;
using NPOI.SS.UserModel;
using NPOI.XWPF.UserModel;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Bcpg;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
using static NPOI.HSSF.Util.HSSFColor;

namespace DFGK_WMS.Repository
{
    internal class TOutboundOrderDetailRepository : BaseRepository<TShippingOrderDetail>, ITOutboundOrderDetailRepository
    {
        private readonly IBarCodeRuleRepository barCodeRuleRepository;
        private readonly ITCellRepository tCell;

        public TOutboundOrderDetailRepository(DFGK_DB context, IMapper mapper, IBarCodeRuleRepository barCodeRuleRepository, ITCellRepository tCell) : base(context, mapper)
        {
            this.barCodeRuleRepository = barCodeRuleRepository;
            this.tCell = tCell;
        }

        #region 基础接口



        /// <summary>
        /// 获取出库单明细表数据
        /// </summary>
        /// <param name="criteria"></param>
        /// <returns></returns>
        public TShippingOrderDetail GetShippingOrderDetail(int OrderId)
        {
            var list = Context.TShippingOrderDetails
                .Where(x => x.Id == OrderId)
                .FirstOrDefault();

            return list;

        }

        /// <summary>
        /// 获取出库单明细  多个物料版本
        /// </summary>
        /// <returns></returns>
        public List<TShippingOrderDetailPlusDTOGroup> GetTShippingOrderDetailPlus(string key, int pageIndex, int pageSize, out int totalcount)
        {
            var list = Context.TShippingOrderDetails.AsEnumerable().Where(s => s.Status == 0).OrderByDescending(s => s.CreateDate).GroupBy(s => s.OrderSn);
            var lockCelllist = Context.TShippingLockCells.AsNoTracking();
            List<TShippingOrderDetailPlusDTOGroup> resList = new List<TShippingOrderDetailPlusDTOGroup>();
            foreach (var item in list)
            {
                var keyy = item.Key;
                var lockCellList = new List<TShippingLockCell>();
                foreach (var value in item)
                {
                    var lockCell = lockCelllist.AsQueryable().Where(s => s.OrderDetailId == value.Id && s.IsPicking == false);
                    if (!string.IsNullOrEmpty(key))
                    {
                        lockCell = lockCell.Where(x => x.MaterialCode.Contains(key));
                    }
                    if (lockCell != null && lockCell.Count() > 0)
                    {
                        foreach (var item1 in lockCell)
                        {
                            lockCellList.Add(item1);
                        }
                    }
                }
                if (lockCellList != null && lockCellList.Count() > 0)
                {
                    resList.Add(new TShippingOrderDetailPlusDTOGroup(keyy, false, lockCellList));
                }
            }
            totalcount = resList.Count;
            resList = resList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return resList;

        }

        // 根据托盘条码号查询库存表
        public TInventory GetInventory(string PalletBarcode)
        {
            var list = Context.TInventories
                .FirstOrDefault(x => x.PalletBarcode == PalletBarcode);

            if (list == null)
            {
                return null;
            }
            return list;
        }

        /// <summary>
        /// 根据垛条码查询垛主
        /// </summary>
        /// <param name="PalletBarcode"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<TStackingStorage> GetStackingStacker(string[] PalletBarcode)
        {
            var list = new List<TStackingStorage>();
            foreach (var item in PalletBarcode)
            {
                list.AddRange(Context.TStackingStorages.Where(x => x.PalletBarcode == item).ToList());
            }
            return list;
        }

        /// <summary>
        /// 首次提交，更新库存中状态
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public int UpdStatus(int id)
        {
            int count = 0;
            var inventory = Context.TInventory.FirstOrDefault(x => x.MaterialId == id);
            if (inventory != null)
            {
                inventory.Status = 4;

                inventory.IsLock = inventory.IsLock.HasValue ? (bool)inventory.IsLock : false;

                count = count += 1;

                // 提交对数据库的更改
                Context.SaveChanges();
            }
            else
            {
                return 0;
            }
            return count;
        }


        /// <summary>
        /// 根据ID查询入库垛信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<TStackingStorage> GetStackingStorages(string[] PalletBarcode)
        {
            var list = new List<TStackingStorage>();
            foreach (var item in PalletBarcode)
            {
                var staSto = Context.TStackingStorages.Where(x => x.PalletBarcode == item);
                if (staSto != null)
                {
                    list.AddRange(staSto);
                }
            }
            return list.ToList();
        }



        /// <summary>
        /// 拣选出库
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool AddPickingOutbound(TPickingStationDatum item)
        {
            TPickingStationDatum pickingStationDatum = new TPickingStationDatum();
            pickingStationDatum.child = new List<TPickingStationDataDetail>();

            var addedItem = Context.TPickingStationData.Add(item);
            Context.SaveChanges();

            if (addedItem != null)
            {
                int newPickingStationDataId = addedItem.Entity.Id;

                TPickingStationDataDetail pickingStationDataDetail = new TPickingStationDataDetail();
                pickingStationDataDetail.PickingStationDataId = newPickingStationDataId;

                pickingStationDataDetail.PickingStationDataId = newPickingStationDataId;
                pickingStationDataDetail.StationId = item.child[0].StationId;
                pickingStationDataDetail.StationCode = item.child[0].StationCode;
                pickingStationDataDetail.PackageBarcode = item.child[0].PackageBarcode;
                pickingStationDataDetail.Barcode = item.child[0].Barcode;
                pickingStationDataDetail.SkuNum = item.child[0].SkuNum;
                pickingStationDataDetail.IsSku = item.child[0].IsSku;
                pickingStationDataDetail.IsSelected = item.child[0].IsSelected;
                pickingStationDataDetail.PickedNum = item.child[0].PickedNum;
                pickingStationDataDetail.BarcodeRange = item.child[0].BarcodeRange;

                Context.TPickingStationDataDetails.Add(pickingStationDataDetail);

                // 再次保存以关联TPickingStationData和TPickingStationDataDetail之间的关系
                Context.SaveChanges();

                return true;
            }

            return false;
        }


        /// <summary>
        /// 获取拣选出库
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<TPickingStationDatum> GetPickingStationDatum(int id)
        {
            var list = Context.TPickingStationData
                .Where(x => x.Id == id);

            return list.ToList();
        }

        /// <summary>
        /// 获取拣选出库详情
        /// </summary>
        /// <param name="PickingStationDataId"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<TPickingStationDataDetail> GetPickingStationDetail(int PickingStationDataId)
        {
            var list = Context.TPickingStationDataDetails
                .Where(x => x.PickingStationDataId == PickingStationDataId);

            return list.ToList();
        }

        /// <summary>
        /// 获取库存数量
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public decimal GetInventoryQuantity(int? MaterialId)
        {
            var Qty = Context.TInventories
                .Where(x => x.MaterialId == MaterialId)
                .Select(x => x.AvailableQty).Sum();
            if (Qty > 0)
            {
                return Qty.Value;
            }
            return 0;
        }

        /// <summary>
        /// 减去库存数量并修改库存状态
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool GetDwindleNumbers(TInventory upd, decimal? num)
        {
            if (upd == null)
            {
                return false;
            }
            upd.AvailableQty = upd.AvailableQty - num;
            //upd.Status = 1;

            Context.SaveChanges();

            return true;

        }


        /// <summary>
        /// 查询指令记录
        /// </summary>
        /// <param name="criteria"></param>
        /// <param name="shippingOrderDetail"></param>
        /// <returns></returns>
        public List<TInstruct> GetInstructsCount(InstructCriteriaModel criteria, TShippingOrderDetail shippingOrderDetail)
        {
            var list = Context.TInstructs.AsQueryable();

            list = list.Where(t => t.InstructType == 2 && t.Status == 2);

            return list.ToList();
        }

        // 插入日志
        public int InsertLog(TLog log)
        {
            try
            {
                Context.TLogs.Add(log);
                Context.SaveChanges();
                return 1;
            }
            catch
            {
                return -1;
            }
        }

        /// <summary>
        /// 更新计划任务
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public int InsertScheduledTask(TScheduledTask item)
        {
            try
            {
                Context.TScheduledTasks.Add(item);

                return Context.SaveChanges();
            }
            catch { return -1; }
        }

        /// <summary>
        /// 根据单号查询出库单明细数据并修改状态
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool UpdateShippingOrderDetail(int id)
        {
            var list = Context.TShippingOrderDetails
                .Where(x => x.Id == id)
                .FirstOrDefault();
            if (list == null)
            {
                return false;
            }
            list.IsOutOrderReview = false;

            return true;

        }

        /// <summary>
        /// 更新库房信息
        /// </summary>
        /// <param name="shippingOrderDetail"></param>
        /// <returns></returns>
        public bool UpdInstructsCount(TShippingOrderDetail shippingOrderDetail)
        {
            var list = Context.TInstructs.FirstOrDefault();
            list.WarehouseCode = shippingOrderDetail.WarehouseCode;
            list.Status = 2;
            if (list != null)
            {
                return true;
            }
            return false;
        }


        /// <summary>
        /// 获取入库垛信息及状态
        /// </summary>
        /// <param name="PalletBarcode"></param>
        /// <param name="reorderid"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        public TStackingStorage GetStackingStorageStatus(string PalletBarcode, int reorderid, int status)
        {
            var list = Context.TStackingStorages
                .Where(x => x.PalletBarcode == PalletBarcode && x.Status == status)
                .FirstOrDefault();

            return list;
        }

        /// <summary>
        /// 获取仓位信息
        /// </summary>
        /// <param name="palletBarcode"></param>
        /// <returns></returns>
        public TCell GetInventoryByTCell(string palletBarcode)
        {
            TInventory inventoryModel = GetInventory(palletBarcode);

            if (inventoryModel == null)
            {
                return null;
            }

            var cell = Context.TCells.Where(x => x.Code == inventoryModel.LocationCode).FirstOrDefault();
            return cell;

        }

        /// <summary>
        /// 更新仓位信息
        /// </summary>
        /// <param name="tcell"></param>
        /// <returns></returns>
        public bool UpdateCell(TCell tcell)
        {
            try
            {
                if (tcell == null)
                {
                    return false;
                }
                tcell.FullStatus = 0;
                tcell.IsLock = false;
                tcell.BusinessType = 0;
                tcell.ModifyDate = DateTime.Now;
                tcell.Status = 1;

                return true;
            }
            catch
            {
                return false;
            }

        }

        /// <summary>
        /// 更新垛主表的状态为失效状态
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool UpdateStackingStorage(TStackingStorage model)
        {
            //var sobj = Context.TStackingStorages
            //    .Find(model.Id);

            if (model == null)
            {
                return false;
            }
            if (model.Qty <= 0)
            {
                //model.Status = 0;
                Context.TStackingStorages.Remove(model);
            }
            else
            {
                model.ModifyDate = DateTime.Now;
            }
            return true;
        }

        /// <summary>
        /// 删除库存表数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool DeleteInventory(int id)
        {
            try
            {
                var list = Context.TInventories.FirstOrDefault(x => x.Id == id);
                if (list == null)
                {
                    return false;
                }
                Context.TInventories.Remove(list);
                Context.SaveChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }
        #endregion

        #region 执行出库单
        /// <summary>
        /// 执行出库单
        /// </summary>
        /// <param name="opUser"></param>
        /// <param name="id"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        public bool RunShippingOrderDetail(int id, TShippingOrderDetail shippingOrderDetail, out string message)
        {
            message = "";
            using (var tran = Context.Database.BeginTransaction())
            {
                try
                {
                    if (id <= 0)
                    {
                        message = "请求参数有误，请检查请求参数";
                        return false;
                    }
                    bool result = false;


                    var list = GetInstructsCount(new InstructCriteriaModel
                    {
                        WarehouseCode = shippingOrderDetail.WarehouseCode,
                        Status = 2,
                    }, shippingOrderDetail);

                    if (list.Count > 0)
                    {
                        message = "存在盘点任务未完成";
                        tran.Rollback();
                        return false;
                    }
                    if (UpdStatus(shippingOrderDetail.MaterialId) <= 0)
                    {
                        message = "更新库存状态失败";
                        tran.Rollback();
                        return false;
                    }
                    TShippingOrderDetail shippingOrderDetailModel = GetShippingOrderDetail(id);
                    shippingOrderDetailModel.Status = (int)EmBillStatus.Executing;
                    shippingOrderDetailModel.ModifyDate = DateTime.Now;
                    shippingOrderDetailModel.ModifyUserId = shippingOrderDetail.CreateUserId;
                    shippingOrderDetailModel.ModifyUserName = shippingOrderDetail.ModifyUserName;


                    //if (ValidScheduledTaskData(shippingOrderDetail.Id))
                    //{
                    //   tran.Rollback();
                    //    return false;
                    // }

                    result = InsertScheduledTask(new TScheduledTask
                    {
                        RecordType = 2,
                        RecordId = shippingOrderDetail.Id,
                        WarehouseId = shippingOrderDetail.WarehouseId,
                        WarehouseName = shippingOrderDetail.WarehouseName,
                        WarehouseCode = shippingOrderDetail.WarehouseCode,
                        Priority = (shippingOrderDetail.IsOnceOut.HasValue && shippingOrderDetail.IsOnceOut.Value) ? 999 : 0,
                        RefId = null,
                        Data = null,
                        Status = 0,
                        Title = "出库任务启动",
                        CreateDate = DateTime.Now,
                        CreateUserId = shippingOrderDetail.CreateUserId,
                        CreateUserName = shippingOrderDetail.CreateUserName,
                    }) > 0;
                    if (!result)
                    {
                        message = "出库任务启动失败";
                        tran.Rollback();
                        return false;
                    }

                    result = InsertLog(new TLog
                    {
                        LogType = 1,
                        ActionType = 0,
                        RecordType = 2,
                        RecordId = id,
                        Status = 1,
                        CreateDate = DateTime.Now,
                        UserId = shippingOrderDetail.CreateUserId,
                        UserName = shippingOrderDetail.CreateUserName,
                        RealName = shippingOrderDetail.ModifyUserName,
                        ModuleName = "出库单",
                        Description = shippingOrderDetail.ModifyUserName + "执行了出库单" + shippingOrderDetail.OrderSn
                    }) > 0;
                    if (!result)
                    {
                        message = "保存失败";
                        tran.Rollback();
                        return false;
                    }
                    tran.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    tran.Rollback();
                    return false;
                }
            }

        }

        #endregion


        #region 出库复核
        /// <summary>
        /// 出库复核
        /// </summary>
        /// <param name="OrderDTO"></param>
        /// <returns></returns>
        public bool SubmitOutInventoryReview(SubmitOutListDTO OrderDTO, out string message)
        {
            message = "";
            try
            {
                if (OrderDTO.orderDetId <= 0)
                {
                    message = "参数传入错误";
                    return false;
                }

                bool result = false;
                {
                    TShippingOrderDetail shippingOrderDetail = GetShippingOrderDetail(OrderDTO.orderDetId);
                    //找出出库要出托盘
                    var lcokCell = Context.TShippingLockCells.Where(s => s.OrderDetailId == OrderDTO.orderDetId && s.PalletBarcode == OrderDTO.palletBarcode[0]).FirstOrDefault();
                    if (lcokCell == null)
                    {
                        message = "托盘查询失败";
                        return false;
                    }
                    var lockCellPalletBarCode = new List<string>
                    {
                        lcokCell.PalletBarcode
                    };
                    var inv = Context.TInventory.Find(lcokCell?.InventoryId);
                    //如果出库数量大于库存数量 不行  
                    if (OrderDTO.qty > inv?.AvailableQty)
                    {
                        message = "出库数量大于预期数量";
                        return false;
                    }
                    //校验所有的出库推盘
                    foreach (var item in OrderDTO.palletBarcode)
                    {
                        if (!lockCellPalletBarCode.Contains(item))
                        {
                            message = "出库托盘校验失败";
                            return false;
                        }
                    }

                    //var updShippingOrderDetail = UpdInstructsCount(shippingOrderDetail);
                    //if (!updShippingOrderDetail)
                    //{
                    //    message = "更新库房信息失败";
                    //    return false;
                    //}
                    int logId = InsertLog(new TLog
                    {
                        LogType = 1,
                        ActionType = 0,
                        RecordType = 0,
                        RecordId = OrderDTO.orderDetId,
                        Status = 1,
                        CreateDate = DateTime.Now,
                        UserId = OrderDTO.createUserld,
                        UserName = OrderDTO.createUser,
                        RealName = OrderDTO.nowUserRealName,
                        ModuleName = "出库复核",
                        Description = string.Format("出库复核【{0}】,数量【{1}】，操作人{2}", shippingOrderDetail.WarehouseName, shippingOrderDetail.Qty, OrderDTO.nowUserRealName),
                    });
                    result = logId > 0;
                    if (!result)
                    {
                        message = "出库复核失败";
                        return false;
                    }

                    //更新复核状态
                    result = UpdateShippingOrderDetail(OrderDTO.orderDetId);
                    if (!result)
                    {
                        message = "更新复核状态失败";
                        return false;
                    }
                    return true;
                }
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        #endregion

        #region 出库复核Plus

        /// <summary>
        /// 出库复核Plus
        /// </summary>
        /// <param name="OrderDTO"></param>
        /// <returns></returns>
        public bool SubmitOutInventoryReviewPlus(SubmitOutListDTO OrderDTO, out string message)
        {
            message = "";
            try
            {
                if (OrderDTO.orderDetId <= 0)
                {
                    message = "参数传入错误";
                    return false;
                }

                bool result = false;
                {
                    TShippingOrderDetail shippingOrderDetail = GetShippingOrderDetail(OrderDTO.orderDetId);
                    #region 岳哲
                    //找出出库要出托盘
                    var lcokCell = Context.TShippingLockCells.Where(s => s.OrderDetailId == OrderDTO.orderDetId).FirstOrDefault();
                    if (lcokCell == null)
                    {
                        message = "托盘查询失败";
                        return false;
                    }
                    var lockCellPalletBarCode = new List<string>();
                    foreach (string palletBarcode in OrderDTO.palletBarcode)
                    {
                        lockCellPalletBarCode.Add(palletBarcode);
                    }
                    var inv = Context.TInventory.Find(lcokCell?.InventoryId);
                    //如果出库数量大于库存数量 不行  
                    if (OrderDTO.qty > inv?.AvailableQty)
                    {
                        message = "出库数量大于预期数量";
                        return false;
                    }
                    //校验所有的出库推盘
                    foreach (var item in OrderDTO.palletBarcode)
                    {
                        if (!lockCellPalletBarCode.Contains(item))
                        {
                            message = "出库托盘校验失败";
                            return false;
                        }
                    }

                    #endregion

                    var updShippingOrderDetail = UpdInstructsCount(shippingOrderDetail);
                    if (!updShippingOrderDetail)
                    {
                        message = "更新库房信息失败";
                        return false;
                    }
                    int logId = InsertLog(new TLog
                    {
                        LogType = 1,
                        ActionType = 0,
                        RecordType = 0,
                        RecordId = OrderDTO.orderDetId,
                        Status = 1,
                        CreateDate = DateTime.Now,
                        UserId = OrderDTO.createUserld,
                        UserName = OrderDTO.createUser,
                        RealName = OrderDTO.nowUserRealName,
                        ModuleName = "出库复核",
                        Description = string.Format("出库复核【{0}】,数量【{1}】，操作人{2}", shippingOrderDetail.WarehouseName, shippingOrderDetail.Qty, OrderDTO.nowUserRealName),
                    });
                    result = logId > 0;
                    if (!result)
                    {
                        message = "插入出库复核日志失败";
                        return false;
                    }
                    //更新复核状态
                    result = UpdateShippingOrderDetail(OrderDTO.orderDetId);
                    if (!result)
                    {
                        message = "更新复核状态失败";
                        return false;
                    }
                    return true;
                }
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        #endregion

        #region 出库解绑
        /// <summary>
        /// 出库解绑添加指令
        /// </summary>
        /// <param name="palletBarcode"></param>
        /// <param name="user"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        public bool HandleUnbindOfOutstorage(SubmitOutListDTO OrderDTO, out string message)
        {
            message = "";
            try
            {
                bool result = false;
                //垛id
                int staciid = 0;
                //物料id
                int materid = 0;
                //托盘条码
                string pacode = "";
                //批次
                string? batch = "";
                foreach (var palletBarcode in OrderDTO.palletBarcode)
                {
                    pacode = palletBarcode;
                }
                //TInventory inventoryModel = GetInventory(pacode);
                //拿到库存id
                int? invid = Context.TShippingLockCells.FirstOrDefault(x => x.OrderDetailId == OrderDTO.orderDetId)?.InventoryId;
                if (invid == null)
                {
                    message = "获取库存id有误！";
                    return false;
                }
                TInventory? inventoryModel = Context.TInventory.Find(invid);
                //状态修改出库在途         
                if (inventoryModel == null)
                {
                    message = "获取库存信息失败";
                    return false;
                }
                inventoryModel.Status = 4;
                var inventorylist = Context.TInventory.Where(x => x.PalletBarcode == pacode && x.Status == 1);
                if (inventorylist.Any())
                {
                    foreach (var item in inventorylist)
                    {
                        item.Status = 4;
                        Context.TInventory.Update(item);
                    }
                }
                //TStackingStorage model = this.GetStackingStorageStatus(pacode, OrderDTO.orderDetId, 1);
                TStackingStorage? model = Context.TStackingStorages.FirstOrDefault(x => x.RelatedOrderDetailId == inventoryModel.RelatedOrderDetailId && x.Status == 1);
                if (model == null)
                {
                    message = "获取垛条码信息失败";
                    return false;
                }
                staciid = model.Id;
                pacode = model.PalletBarcode;
                #region 
                //var tcell = GetInventoryByTCell(pacode);
                //result = UpdateCell(tcell);
                //if (!result)
                //{
                //    message = "获取仓位信息";
                //    return false;
                //}
                //model.Qty = model.Qty - OrderDTO.qty;
                //result = UpdateStackingStorage(model);
                //if (!result)
                //{
                //    message = "更新垛条码信息失败";
                //    return false;
                //}

                //var inventoryOrder = GetTInventoryId(pacode);
                // 获取库存数量
                //var qty = GetInventoryQuantity(inventoryModel.MaterialId);

                //if (inventoryModel.AvailableQty <= 0)
                //{
                //    message = "获取库存数量失败";
                //    return false;
                //}
                #endregion
                #region 
                //// 库存数量减去需要出库的数量
                //if (inventoryModel.AvailableQty - OrderDTO.qty == 0)
                //{
                //    result = DeleteInventory(inventoryModel.Id);
                //    if (!result)
                //    {
                //        message = "删除库存信息失败";
                //        return false;
                //    }
                //    // 如果出完库就修改仓位锁定表数据 
                //    if (!UpdTShippingLockCell(OrderDTO.orderDetId, OrderDTO.palletBarcode[0]))
                //    {
                //        return false;
                //    }
                //}
                //else
                //{
                //    // 减去库存数量并修改库存状态
                //    if (!GetDwindleNumbers(inventoryModel, OrderDTO.qty))
                //    {
                //        message = "修改库存状态失败";
                //        return false;
                //    }
                //    // 如果没有出完库就更新仓位锁定表中的库存数量
                //    var lockCell = Context.TShippingLockCells.Where(s => s.OrderDetailId == OrderDTO.orderDetId && s.PalletBarcode == OrderDTO.palletBarcode[0]).FirstOrDefault();
                //    if (lockCell != null)
                //    {
                //        lockCell.InventoryQty -= OrderDTO.qty;
                //        lockCell.IsPicking = true;
                //        Context.TShippingLockCells.Update(lockCell);
                //        Context.SaveChanges();
                //    }
                //}
                #endregion
                // 出库单数量修改 状态修改
                var shippingOrderDetail = Context.TShippingOrderDetails.Find(OrderDTO.orderDetId);
                if (shippingOrderDetail == null)
                {
                    message = "获取出库单信息失败";
                    return false;
                }
                var lockList = Context.TShippingLockCells.Where(x => x.OrderDetailId == shippingOrderDetail.Id);
                if (lockList == null)
                {
                    message = "未查询到单号" + shippingOrderDetail.OrderSn + "的出库单详情";
                    return false;
                }
                shippingOrderDetail.Status = 3;
                materid = lockList.First().MaterialId == null ? 0 : Convert.ToInt32(lockList.First().MaterialId);
                batch = lockList.First().BatchNo == null ? "" : lockList.First().BatchNo;
                var cellList = Context.TCells.Where(x => x.Code == lockList.First().CellCode);
                if (cellList == null)
                {
                    message = "未查询到仓位" + lockList.First().CellCode;
                }
                #region
                //if (shippingOrderDetail != null)
                //{
                //    shippingOrderDetail.ShippedQty += OrderDTO.qty;
                //    if (shippingOrderDetail.ShippedQty == shippingOrderDetail.Qty)
                //    {
                //        shippingOrderDetail.Status = 4;
                //    }

                //    Context.SaveChanges();
                //}
                //else
                //{
                //    message = "出库单状态修改失败";
                //    return false;
                //}
                #endregion
                //站台编码
                string stacode = OrderDTO.StationCode;

                int logId = InsertLog(new TLog
                {
                    LogType = 1,
                    ActionType = 7,
                    Status = 1,
                    CreateDate = DateTime.Now,
                    UserId = OrderDTO.createUserld,
                    UserName = OrderDTO.nowUserRealName,
                    RealName = OrderDTO.nowUserRealName,
                    //ModuleName = model.ModuleName,
                    Description = "出库解绑成功",
                });
                int a=0, b=0;
                string code = "";
                MatchCollection match = Regex.Matches(cellList.First().Code, @"\d");
                if (match.Count >= 2)
                {
                    a = Convert.ToInt32(match[0].Value);
                    b = Convert.ToInt32(match[1].Value);
                    if (a == 4 && (a + b == 5 || a + b == 6))
                    {
                        code = "1806";
                    }
                }
                #region 添加指令
                TInstruct inobj = new TInstruct();
                inobj.WarehouseCode = "A2";
                inobj.Status = 2;
                inobj.FromLocation = stacode;
                inobj.ToLocation = inventoryModel.LocationCode;
                inobj.StackingStorageId = model.Id;
                inobj.WorkDeviceType = code.Length > 0 ? 2 : 1;
                inobj.InstructType = 2;
                inobj.Action = 0;
                inobj.RelatedOrderId = OrderDTO.orderDetId;
                inobj.DeviceCode = "";
                inobj.ExpectedToLocation = inventoryModel.LocationCode;
                inobj.InstructIndex = 1;
                inobj.PalletBarcode = pacode;
                inobj.ScanedBarcode = pacode;
                inobj.Priority = 9999;
                inobj.Qty = OrderDTO.qty;
                inobj.FinishedQty = 0;
                inobj.StartTime = DateTime.Now;
                inobj.BusinessGroupId = Guid.NewGuid();
                inobj.BusinessType = (int)EmBusinessType.Out;
                inobj.BillType = (int)shippingOrderDetail.BillType.GetValueOrDefault();
                inobj.LogicalCellAddr = "";
                Context.TInstructs.Add(inobj);
                bool result2 = Context.SaveChanges() > 0;
                if (!result2)
                {
                    message = "添加指令失败！";
                    return false;
                }
                #endregion
                #region 添加上架单
                int putid2 = 0;
                var putobj = Context.TPutawayOrders.FirstOrDefault(x => x.SourceType == 2 && x.Status == 1 && x.PalletBarcode == pacode);
                if (putobj == null)
                {
                    string str = DateTime.Now.ToString("yyyyMMddHHmmssfff");// + randNum.ToString("0000");
                    string putawayCode = "OUT" + str;
                    TPutawayOrder putawayOrder = new TPutawayOrder();
                    putawayOrder.Code = putawayCode;
                    putawayOrder.BillType = 2;
                    putawayOrder.StackingStorageId = staciid;
                    //如果出库数量等于库存数量，整托盘出库-随机分配站台
                    if (shippingOrderDetail.Qty == inventoryModel.AvailableQty && code.Length == 0)
                    {
                        var putlist = Context.TPutawayOrders.AsNoTracking().Where(x => x.SourceType == 2 && x.Status == 1).Select(x => x.SiteCode);
                        //查询是直入/环线模式
                        string? stationid = Context.TStations.Find(2)?.Remark;
                        if (stationid == "1")
                        {
                            for (int i = 1100; i <= 1700;)
                            {
                                if (putlist.Contains(i.ToString()))
                                {
                                    i += 100;
                                }
                                else
                                {
                                    putawayOrder.SiteCode = i.ToString();
                                    break;
                                }
                            }
                            if (string.IsNullOrEmpty(putawayOrder.SiteCode) || putawayOrder.SiteCode.Length <= 0)
                            {
                                putawayOrder.SiteCode = stacode;
                            }
                        }
                        else
                        {
                            switch(a)
                            { 
                                case 1:
                                    putawayOrder.SiteCode = "1200";
                                    break;
                                case 2:
                                    putawayOrder.SiteCode = "1400";
                                    break;
                                case 3:
                                    putawayOrder.SiteCode = "1600";
                                    break;
                                case 4:
                                    putawayOrder.SiteCode = "1700";
                                    break;
                            }                                                     
                        }
                    }
                    else
                    {
                        putawayOrder.SiteCode = code.Length > 0 ? "1800" : stacode;
                    }
                    putawayOrder.PalletBarcode = pacode;
                    putawayOrder.Roadway = code.Length > 0 ? code : cellList.First().RoutewayId.ToString();
                    putawayOrder.LocationCode = lockList.First().CellCode;
                    putawayOrder.LocationDepth = lockList.First().CellDepthIndex;
                    putawayOrder.Status = 1;
                    putawayOrder.Qty = shippingOrderDetail.Qty;
                    putawayOrder.CreateDate = DateTime.Now;
                    putawayOrder.CreateUserId = shippingOrderDetail.CreateUserId;
                    putawayOrder.CreateUserName = shippingOrderDetail.CreateUserName;
                    putawayOrder.MaterialId = materid;
                    putawayOrder.MaterialCode = shippingOrderDetail.MaterialCode;
                    putawayOrder.MaterialName = shippingOrderDetail.MaterialName;
                    putawayOrder.OwnerId = shippingOrderDetail.OwnerId;
                    putawayOrder.OwnerName = shippingOrderDetail.OwnerName;
                    putawayOrder.BatchNo = batch;
                    putawayOrder.SmallBatchNo = shippingOrderDetail.SmallBatchNo;
                    putawayOrder.SourceType = 2;
                    putawayOrder.RelatedOrderDetailId = OrderDTO.orderDetId;
                    Context.TPutawayOrders.Add(putawayOrder);
                    if (Context.SaveChanges() <= 0)
                    {
                        message = "添加上架单失败";
                        return false;
                    }
                    putid2 = putawayOrder.Id;
                    #region 堆垛机
                    //获取巷道节点
                    RoadwayCode roadwayCode = new RoadwayCode()
                    {
                        taskCode = putawayOrder.Code,
                        Roadway = putawayOrder.Roadway,
                    };

                    var data = HttpHelper.SendPostRequestes("获取巷道节点", roadwayCode);
                    //LogHelper.LogInformation("巷道节点" + data);
                    //堆垛机出库
                    TaskLiku taskLiku = new TaskLiku()
                    {
                        taskCode = putawayOrder.Code,
                        taskType = "2",
                        startPoint = putawayOrder.LocationCode,
                        //endPositionId = OrderDTO.StationCode,
                        endPoint = data.data
                    };
                    //堆垛机出库和led屏幕显示
                    var ip = LedipShow.Getledip(putawayOrder.SourceType, putawayOrder.Roadway);
                    var start = putawayOrder.SourceType == 2 ? "出库" : "入库";
                    var ledlik = HttpHelper.LedSendPostRequest(new { ip = ip, message = "物料号:" + putawayOrder.MaterialCode + "\\n" + "托盘码" + putawayOrder.PalletBarcode + "\\n" + "状态:" + start + "\\n位置:" + putawayOrder.SiteCode });
                    var taskLikudata = HttpHelper.WCSSendPostRequest("Api/ApiWCS/ReceiveTask", taskLiku);
                    //LogHelper.LogInformation("wcs出入库：" + taskLikudata);
                    #endregion
                }
                else
                    putid2 = putobj.Id;

                TPutawayOrderDetail putawayOrderDetail = new TPutawayOrderDetail();
                putawayOrderDetail.PutawayOrderId = putid2;
                putawayOrderDetail.PalletBarcode = shippingOrderDetail.PalletBarcode;
                putawayOrderDetail.MaterialBarcode = shippingOrderDetail.MaterialCode;
                Context.TPutawayOrderDetails.Add(putawayOrderDetail);
                if (Context.SaveChanges() <= 0)
                {
                    message = "添加上架单明细失败";
                    return false;
                }
                #endregion

                result = logId > 0;
                if (!result)
                {
                    message = "出库解绑失败";
                    return false;
                }
                //HandleUnbindOfOutstorageEnd(inobj, out message);
                return true;
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        /// <summary>
        /// 完成出库解绑
        /// </summary>
        /// <param name="instruct"></param>
        /// <returns></returns>
        private bool HandleUnbindOfOutstorageEnd(TInstruct instruct, out string message)
        {
            //越飞
            //var instobj = Context.TInstructs.FirstOrDefault(x => x.RelatedOrderId == 0 && x.PalletBarcode == "" && x.Status == 2);
            bool result;
            message = "";
            //仓位
            var tell = GetInventoryByTCell(instruct.PalletBarcode);
            instruct.Status = 4;
            instruct.EndTime = DateTime.Now;
            //result = UpdateCell(tell);
            //if (!result)
            //{
            //    message = "获取仓位信息";
            //    return false;
            //}
            int shippid = Convert.ToInt32(instruct.RelatedOrderId);
            //组垛
            TStackingStorage model = this.GetStackingStorageStatus(instruct.PalletBarcode, shippid, 1);
            model.Qty = model.Qty - instruct.Qty;
            result = UpdateStackingStorage(model);
            if (!result)
            {
                message = "更新垛条码信息失败";
                return false;
            }
            TInventory inventoryModel = GetInventory(instruct.PalletBarcode);
            decimal? startQty = inventoryModel.AvailableQty;
            decimal? changeQty = instruct.Qty;
            // 库存数量减去需要出库的数量
            if (inventoryModel.AvailableQty - instruct.Qty == 0)
            {
                result = DeleteInventory(inventoryModel.Id);
                if (!result)
                {
                    message = "删除库存信息失败";
                    return false;
                }
                var pallobj = Context.TPallets.FirstOrDefault(x => x.LocationCode == tell.Code && x.LocationName == tell.Name);
                if (pallobj != null)
                {
                    pallobj.LocationName = string.Empty;
                    pallobj.LocationCode = string.Empty;
                }
                tell.FullStatus = 0;
                tell.IsLock = false;
                tell.BusinessType = 0;
                tell.ModifyDate = DateTime.Now;
                tell.Status = 1;
                Context.TCells.Update(tell);
                Context.SaveChanges();
                // 如果出完库就修改仓位锁定表数据 
                if (!UpdTShippingLockCell(shippid, instruct.PalletBarcode))
                {
                    return false;
                }
            }
            else
            {
                // 减去库存数量并修改库存状态
                if (!GetDwindleNumbers(inventoryModel, instruct.Qty))
                {
                    message = "修改库存状态失败";
                    return false;
                }
                // 如果没有出完库就更新仓位锁定表中的库存数量
                var lockCell = Context.TShippingLockCells.Where(s => s.OrderDetailId == instruct.RelatedOrderId && s.PalletBarcode == instruct.PalletBarcode).FirstOrDefault();
                if (lockCell != null)
                {
                    lockCell.InventoryQty -= instruct.Qty;
                    lockCell.IsPicking = true;
                    Context.TShippingLockCells.Update(lockCell);
                    Context.SaveChanges();
                }
            }

            var shippingOrderDetail = Context.TShippingOrderDetails.Find(shippid);
            var lockList = Context.TShippingLockCells.Where(x => x.OrderDetailId == shippid);
            if (lockList == null)
            {
                message = "未查询到单号" + shippingOrderDetail.OrderSn + "的出库单详情";
                return false;
            }

            if (shippingOrderDetail != null)
            {
                shippingOrderDetail.ShippedQty += instruct.Qty;
                if (shippingOrderDetail.ShippedQty == shippingOrderDetail.Qty)
                {
                    shippingOrderDetail.Status = 4;
                }
                Context.SaveChanges();
            }
            else
            {
                message = "出库单状态修改失败";
                return false;
            }
            //库存流水
            var inventoryLog = new TInventoryLog
            {
                SourceType = 1,
                SourceSn = shippingOrderDetail.OrderSn,
                WarehouseId = shippingOrderDetail.WarehouseId,
                WarehouseName = shippingOrderDetail.WarehouseName,
                AreaName = shippingOrderDetail.AreaName,
                LocationCode = inventoryModel.LocationCode,
                PalletBarcode = inventoryModel.PalletBarcode,
                OwnerId = shippingOrderDetail.OwnerId,
                OwnerName = shippingOrderDetail.OwnerName,
                MaterialId = inventoryModel.MaterialId,
                MaterialCode = inventoryModel.MaterialCode,
                MaterialName = inventoryModel.MaterialName,
                BatchNo = inventoryModel.BatchNo,
                StartQty = startQty,
                ChangeQty = changeQty,
                EndQty = startQty - changeQty, //使用库存数量减去实际出库数量 等于最终数量
                BaseUnitId = 0,
                BaseUnitName = inventoryModel.UnitName,
                Remark = "",
                CreateDate = DateTime.Now,
                CreateUserId = shippingOrderDetail.CreateUserId,
                CreateUser = shippingOrderDetail.CreateUserName,
                SmallBatchNo = "",

            };
            Context.TInventoryLogs.Add(inventoryLog);
            Context.SaveChanges();
            return true;
        }
        #endregion


        #region 出库解绑Plus

        /// <summary>
        /// 出库解绑Plus
        /// </summary>
        /// <param name="palletBarcode"></param>
        /// <param name="user"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        public bool HandleUnbindOfOutstoragePlus(SubmitOutListDTO OrderDTO, out string message)
        {
            message = "";
            try
            {
                bool result = false;

                foreach (var palletBarcode in OrderDTO.palletBarcode)
                {
                    var pall = Context.TStackingStorages.Where(x => x.PalletBarcode == palletBarcode).FirstOrDefault();
                    if (pall == null)
                    {
                        message = "垛条码信息查询失败";
                        return false;
                    }
                    TStackingStorage model = this.GetStackingStorageStatus(palletBarcode, OrderDTO.orderDetId, pall.Status);
                    if (model == null)
                    {
                        message = "获取垛条码信息失败";
                        return false;
                    }
                    TInventory inventoryModel = GetInventory(palletBarcode);
                    if (inventoryModel == null)
                    {
                        message = "获取库存信息失败";
                        return false;
                    }

                    var tcell = GetInventoryByTCell(palletBarcode);
                    result = UpdateCell(tcell);
                    if (!result)
                    {
                        message = "获取仓位信息";
                        return false;
                    }

                    result = UpdateStackingStorage(model);
                    if (!result)
                    {
                        message = "更新垛条码信息失败";
                        return false;
                    }

                    var inventoryOrder = GetTInventoryId(palletBarcode);

                    // 获取库存数量
                    var qty = GetInventoryQuantity(inventoryOrder.MaterialId);

                    if (qty < 0)
                    {
                        message = "获取库存数量失败";
                        return false;
                    }

                    // 库存数量减去需要出库的数量
                    if (inventoryOrder.AvailableQty - OrderDTO.qty == 0)
                    {
                        result = DeleteInventory(inventoryModel.Id);
                        if (!result)
                        {
                            message = "删除库存信息失败";
                            return false;
                        }
                        // 如果出完库就修改仓位锁定表数据 
                        if (!UpdTShippingLockCell(OrderDTO.orderDetId, OrderDTO.palletBarcode[0]))
                        {
                            Context.TLogs.Add(new TLog()
                            {
                                ActionType = 4,
                                CreateDate = DateTime.Now,
                                Description = "仓位修改表修改状态失败，托盘：" + OrderDTO.palletBarcode[0],
                                LogType = 1,
                                ModuleName = "PDA出库",
                            });
                            return false;
                        }


                        // 往库存流水表添加数据
                        CreateTInventoryLogs(OrderDTO);


                    }
                    else
                    {
                        // 减去库存数量并修改库存状态
                        if (!GetDwindleNumbers(inventoryOrder, OrderDTO.qty))
                        {
                            message = "修改库存状态失败";
                            return false;
                        }
                        // 如果没有出完库就更新仓位锁定表中的库存数量
                        var lockCell = Context.TShippingLockCells.Where(s => s.OrderDetailId == OrderDTO.orderDetId).FirstOrDefault();
                        if (lockCell != null)
                            lockCell.InventoryQty -= OrderDTO.qty;

                        CreateTInventoryLogs(OrderDTO);

                    }

                    // 出库单数量修改 状态修改
                    var shippingOrderDetail = Context.TShippingOrderDetails.Find(OrderDTO.orderDetId);
                    if (shippingOrderDetail != null)
                    {
                        shippingOrderDetail.ShippedQty += OrderDTO.qty;
                        if (shippingOrderDetail.ShippedQty == shippingOrderDetail.Qty)
                        {
                            shippingOrderDetail.Status = 4;
                        }

                        //TShippingGoodsDetail shippingGoods = Context.TShippingGoodsDetails.Where(s => s.OrderDetailId == OrderDTO.orderDetId && s.PalletBarcode == OrderDTO.palletBarcode[0]).FirstOrDefault();
                        //if (shippingGoods == null)
                        //{
                        //    return false;
                        //}
                        //shippingGoods.Status = 1;
                        //Context.TShippingGoodsDetails.Update(shippingGoods);
                        Context.SaveChanges();
                    }
                    else
                    {
                        message = "出库单状态修改失败";
                        return false;
                    }

                    int logId = InsertLog(new TLog
                    {
                        LogType = 1,
                        ActionType = 7,
                        Status = 1,
                        CreateDate = DateTime.Now,
                        UserId = OrderDTO.createUserld,
                        UserName = OrderDTO.nowUserRealName,
                        RealName = OrderDTO.nowUserRealName,
                        //ModuleName = model.ModuleName,
                        Description = "出库解绑成功",
                    });
                    result = logId > 0;
                    if (!result)
                    {
                        message = "出库解绑失败";
                        return false;
                    }
                }


                return true;
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        /// <summary>
        /// 库存流水添加数据
        /// </summary>
        /// <param name="OrderDetailId"></param>
        /// <returns></returns>
        public bool CreateTInventoryLogs(SubmitOutListDTO OrderDTO)
        {
            var orderDetail = Context.TShippingOrderDetails.Where(s => s.Id == OrderDTO.orderDetId).FirstOrDefault();
            var lockCell = Context.TShippingLockCells.Where(s => s.PalletBarcode == OrderDTO.palletBarcode[0]).FirstOrDefault();
            var inventoryLog = new TInventoryLog
            {
                SourceType = 1,
                SourceSn = orderDetail?.OrderSn,
                WarehouseId = orderDetail?.WarehouseId,
                WarehouseName = orderDetail?.WarehouseName,
                AreaName = orderDetail?.AreaName,
                LocationCode = lockCell?.CellCode,
                PalletBarcode = OrderDTO.palletBarcode[0],
                OwnerId = orderDetail?.OwnerId,
                OwnerName = orderDetail?.OwnerName,
                MaterialId = lockCell?.MaterialId,
                MaterialCode = lockCell?.MaterialCode,
                MaterialName = lockCell?.MaterialName,
                BatchNo = lockCell?.BatchNo,
                StartQty = lockCell?.InventoryQty,
                ChangeQty = OrderDTO.qty,
                EndQty = lockCell?.InventoryQty - OrderDTO.qty, //使用库存数量减去实际出库数量 等于最终数量
                BaseUnitId = orderDetail?.UnitId,
                BaseUnitName = orderDetail?.UnitName,
                Remark = "",
                CreateDate = DateTime.Now,
                CreateUserId = OrderDTO.createUserld,
                CreateUser = OrderDTO.createUser
            };
            Context.TInventoryLog.Add(inventoryLog);
            if (Context.SaveChanges() <= 0)
            {
                Context.TLogs.Add(new TLog()
                {
                    ActionType = 4,
                    CreateDate = DateTime.Now,
                    Description = "库存流水添加失败，托盘：" + OrderDTO.palletBarcode[0],
                    LogType = 1,
                    ModuleName = "PDA出库",
                });
                return false;
            }
            return true;
        }

        #endregion

        /// <summary>
        /// 查询托盘条码,并根据托盘条码查询其他信息
        /// </summary>
        /// <param name="OrderDetailId"></param>
        /// <returns></returns>
        public List<CreateOutboundOrderDTO> GetPalletBarcodePDA(int OrderDetailId)
        {
            var lockCellList = Context.TShippingLockCells.Where(x => x.OrderDetailId == OrderDetailId).Select(s => new CreateOutboundOrderDTO()
            {
                DeliveryOrderID = s.OrderDetailId.GetValueOrDefault(),
                CellCode = s.CellCode,
                PalletBarcode = s.PalletBarcode,
                MaterialsId = s.MaterialId.GetValueOrDefault(),
                MaterialCode = s.MaterialCode,
                BatchNo = s.BatchNo,
                InventoryQty = s.InventoryQty.GetValueOrDefault(),
                OutQty = s.OutQty.GetValueOrDefault()
            });

            List<CreateOutboundOrderDTO> Outbound = lockCellList.ToList();
            return Outbound;
        }


        /// <summary>
        /// 根据垛条码查询库存ID
        /// </summary>
        /// <param name="palletBarcode"></param>
        /// <returns></returns>
        public TInventory GetTInventoryId(string palletBarcode)
        {
            var list = Context.TInventory
                .Where(x => x.PalletBarcode == palletBarcode)
                .FirstOrDefault();

            return list;
        }

        /// <summary>
        /// 修改仓位锁定状态
        /// </summary>
        /// <param name="OrderId"></param>
        /// <returns></returns>
        public bool UpdTShippingLockCell(int OrderId, string palletBarCode)
        {
            try
            {
                var list = Context.TShippingLockCells
               .FirstOrDefault(x => x.OrderDetailId == OrderId && x.PalletBarcode == palletBarCode);
                if (list == null)
                {
                    return false;
                }
                list.IsPicking = true;
                Context.TShippingLockCells.Update(list);
                Context.SaveChanges();
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }


        }


        /// <summary>
        /// 查询出库单相关信息
        /// </summary>
        /// <param name="OrderSn"></param>
        /// <returns></returns>
        public List<CreateOutboundOrderDTO> GetOutboundOrder(string PalletBarcode)
        {
            var list = (
                        from shippingOrder in Context.TShippingOrderDetails
                        join inventory in Context.TInventories on shippingOrder.PalletBarcode equals inventory.PalletBarcode
                        where shippingOrder.PalletBarcode == PalletBarcode
                        select new CreateOutboundOrderDTO
                        {
                            DeliveryOrderID = shippingOrder.Id,
                            WareHouseId = (int)shippingOrder.WarehouseId,
                            MaterialsId = shippingOrder.MaterialId,
                            InventoryId = inventory.Id,
                            CellCode = inventory.LocationCode,
                            AreaCode = shippingOrder.AreaCode
                        }
                    ).ToList();

            return list;
        }

        public bool ChukuMsg(SubmitOutListDTONow OrderDTO, out string errorMsg, out bool isOutOver)
        {
            errorMsg = "出库成功";
            isOutOver = false;
            using (var tran = Context.Database.BeginTransaction())
            {
                try
                {
                    // 出库复核 修改出库单为复核 和已完成
                    var shippingOrder = Context.TShippingOrderDetails.Find(OrderDTO.OrderDetId);
                    if (shippingOrder != null)
                    {
                        shippingOrder.IsOutOrderReview = true;
                        Context.Update(shippingOrder);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "修改出库单为复核失败";
                            return false;
                        }
                    }
                    else
                    {
                        tran.Rollback();
                        errorMsg = "出库单查询失败,出库单id:" + OrderDTO.OrderDetId;
                        return false;
                    }
                    //仓位锁定表 找到要出库的托盘
                    var lockCell = Context.TShippingLockCells.Where(s => s.OrderDetailId == shippingOrder.Id &&
                                                                    s.PalletBarcode == OrderDTO.PalletBarcode[0]).FirstOrDefault();
                    if (lockCell == null)
                    {
                        tran.Rollback();
                        errorMsg = "仓位锁定表查询失败,出库单id:" + shippingOrder.Id;
                        return false;
                    }
                    //查询托盘
                    var tuoPan = Context.TPallets.FirstOrDefault(s => s.PalletBarcode == lockCell.PalletBarcode);
                    if (tuoPan == null)
                    {
                        tran.Rollback();
                        errorMsg = "托盘查询失败,托盘条码:" + lockCell.PalletBarcode;
                        return false;
                    }
                    if (tuoPan.Status == 0)
                    {
                        tran.Rollback();
                        errorMsg = "托盘已被禁用,托盘条码:" + lockCell.PalletBarcode;
                        return false;
                    }


                    //入库单号
                    var ruKuOrderSn = barCodeRuleRepository.GetBarCodeSample(1);

                    //库存记录
                    var inv = Context.TInventories.Where(s => s.PalletBarcode == lockCell.PalletBarcode).FirstOrDefault();
                    if (inv == null)
                    {
                        tran.Rollback();
                        errorMsg = "库存查询失败,托盘：" + lockCell.PalletBarcode;
                        return false;
                    }
                    //库存数量大于出库数量 则减去库存数量
                    if (inv.AvailableQty > lockCell.OutQty)
                    {
                        inv.AvailableQty -= lockCell.OutQty;
                        inv.OutQty += lockCell.OutQty;
                        inv.PickedQty += lockCell.OutQty;
                        //inv.Status = 1;
                        //如果托盘上还有物料了 则把托盘再次进行入库
                        Context.Update(inv);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，库存数量修改失败";
                            return false;
                        }
                        //添加入库单
                        var tROrder = new TReceivingOrderDetail()
                        {
                            AreaCode = inv.AreaCode,
                            AreaName = inv.AreaName,
                            BatchNo = inv.BatchNo,
                            SmallBatchNo = inv.SmallBatchNo,
                            CreateDate = DateTime.Now,
                            InStarDate = DateTime.Now,
                            MaterialCode = inv.MaterialCode,
                            MaterialId = inv.MaterialId,
                            MaterialName = inv.MaterialName,
                            MaterialKeyId = inv.MaterialKeyId,
                            WarehouseCode = inv.WarehouseCode,
                            WarehouseId = inv.WarehouseId,
                            WarehouseName = inv.WarehouseName,
                            OwnerId = inv.OwnerId,
                            OwnerName = inv.OwnerName,
                            SupplierId = inv.SupplierId,
                            SupplierName = inv.SupplierName,
                            UnitId = inv.UnitId,
                            UnitName = inv.UnitName,
                            Qty = inv.AvailableQty,
                            ReceivedQty = 0,
                            StackedQty = inv.AvailableQty,
                            SourceType = 4,
                            OrderSn = ruKuOrderSn,
                            QualityState = 1,
                            Status = 3,
                            PackagedQty = 0,
                            PackQty = 0,
                            BatchNoExplain = inv.BatchNoExplain,
                            OutFactoryDate = inv.OutFactoryDate,
                            ProduceFactory = inv.ProduceFactory,
                            ExpireDate = inv.ExpireDate,
                            Remark = inv.Remark,
                            BillType = 1,
                            CreateUserId = OrderDTO.CreateUserld,
                            CreateUserName = OrderDTO.CreateUser,
                            PalletBarcode = inv.PalletBarcode,
                            Articlebarcode = inv.Articlebarcode,
                        };
                        Context.TReceivingOrderDetails.Add(tROrder);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，入库单添加失败";
                            return false;
                        }
                        Context.TLogs.Add(new TLog()
                        {
                            ActionType = 4,
                            CreateDate = DateTime.Now,
                            Description = $"出库时托盘没出完,{inv.PalletBarcode}进行了回流入库，操作人{OrderDTO.CreateUser}",
                            LogType = 1,
                            ModuleName = "PDA出库",
                            UserId = OrderDTO.CreateUserld,
                            UserName = OrderDTO.CreateUser,
                        });
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，回流入库日志添加失败";
                            return false;
                        }
                        //找出组跺记录
                        var tStackingStorage = Context.TStackingStorages.FirstOrDefault(s => s.PalletBarcode == inv.PalletBarcode && s.Status == 1);
                        if (tStackingStorage == null)
                        {
                            tran.Rollback();
                            errorMsg = "找不到组跺记录，托盘条码：" + inv.PalletBarcode;
                            return false;
                        }
                        //修改指令表的入库单id 这里放在上面是因为要根据组跺表的出库单id修改之前进行查询
                        var Instructobj = Context.TInstructs.FirstOrDefault(i => i.RelatedOrderDetailId == tStackingStorage.RelatedOrderDetailId);
                        if (Instructobj == null)
                        {
                            tran.Rollback();
                            errorMsg = "找不到入库指令，入库单id：" + tStackingStorage.RelatedOrderDetailId;
                            return false;
                        }

                        //找出站台
                        var station = Context.TStations.FirstOrDefault(r => r.WhId == tROrder.WarehouseId);
                        if (station == null)
                        {
                            tran.Rollback();
                            errorMsg = "请配置站台,仓库id:" + tROrder.WarehouseId;
                            return false;
                        }
                        //入库分配仓位
                        var target = tCell.AllocateCell
                        (
                            station,
                            tROrder.MaterialId.GetValueOrDefault(),
                            tROrder.MaterialKeyId.GetValueOrDefault(),
                            tROrder.QualityState,
                            (int)EmHeightType.H1150,
                            out errorMsg,
                            tStackingStorage.LogicalPartCode
                        );
                        if (target == null)
                        {
                            tran.Rollback();
                            errorMsg = "回流入库，未找到入库仓位";
                            return false;
                        }
                        //修改出库单仓位
                        tROrder.LocationCode = target.Code;
                        tROrder.LocationName = target.Name;
                        Context.Update(tROrder);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，入库单分配仓位失败";
                            return false;
                        }
                        //修改组垛仓位
                        tStackingStorage.ActualLocation = target.Code;
                        tStackingStorage.Qty = inv.AllocateQty;
                        tStackingStorage.RelatedOrderDetailId = tROrder.Id;
                        Context.Update(tStackingStorage);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，组跺表修改失败";
                            return false;
                        }
                        //入库指令修改
                        Instructobj.RelatedOrderDetailId = tROrder.Id;
                        Instructobj.ExpectedToLocation = target.Code;
                        Context.Update(Instructobj);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，入库指令修改失败";
                            return false;
                        }
                        //锁仓位
                        var cell = Context.TCells.FirstOrDefault(x => x.Code == target.Code);
                        if (cell == null)
                        {
                            tran.Rollback();
                            errorMsg = "未找到仓位数据";
                            return false;
                        }
                        cell.BusinessType = (int)EmBusinessType.In;
                        cell.IsLock = true;
                        cell.FullStatus = 1;
                        cell.Status = (int)EmCellStatus.Lock;
                        cell.ModifyDate = DateTime.Now;
                        Context.TCells.Update(cell);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，锁定仓位失败";
                            return false;
                        }
                        errorMsg = "出库成功，托盘已添加到入库单";
                    }
                    //库存数量等于出库数量 删除库存
                    else if (inv.AvailableQty == lockCell.OutQty)
                    {
                        //如果托盘上没有物料了 则解绑托盘和入库跺
                        Context.Remove(inv);
                        //入库跺解绑  
                        var tStackingStorage = Context.TStackingStorages.FirstOrDefault(s => s.PalletBarcode == inv.PalletBarcode && s.Status == 1);
                        if (tStackingStorage == null)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，托盘查询不到";
                            return false;
                        }
                        tStackingStorage.Status = 0;
                        Context.Update(tStackingStorage);
                        //托盘解绑
                        var tPalletBarCode = Context.TPallets.FirstOrDefault(s => s.PalletBarcode == inv.PalletBarcode);
                        if (tPalletBarCode == null)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，托盘查询不到";
                            return false;
                        }
                        tPalletBarCode.WarehouseId = 0;
                        tPalletBarCode.LocationCode = null;
                        tPalletBarCode.LocationName = null;
                        tPalletBarCode.ErplocationName = null;
                        tPalletBarCode.ModifyDate = null;
                        Context.Update(tPalletBarCode);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，托盘解绑失败";
                            return false;
                        }
                    }
                    else
                    {
                        tran.Rollback();
                        errorMsg = "出库数量有误,出库数量不能大于托盘剩余数量";
                        return false;
                    }
                    lockCell.IsPicking = true;
                    Context.Update(lockCell);
                    if (Context.SaveChanges() <= 0)
                    {
                        tran.Rollback();
                        errorMsg = "系统错误，库存更改失败";
                        return false;
                    }

                    //修改仓位状态为空仓
                    var cellObj = Context.TCells.FirstOrDefault(s => s.Code == lockCell.CellCode);
                    if (cellObj == null)
                    {
                        tran.Rollback();
                        errorMsg = "仓位寻找失败";
                        return false;
                    }
                    cellObj.FullStatus = 0;
                    Context.Update(cellObj);
                    if (Context.SaveChanges() <= 0)
                    {
                        tran.Rollback();
                        errorMsg = "系统错误，仓位状态修改失败";
                        return false;
                    }


                    //库存流水添加
                    TInventoryLog inventoryLog = new TInventoryLog()
                    {
                        SourceType = 1,
                        SourceSn = shippingOrder.OrderSn,
                        WarehouseId = inv.WarehouseId,
                        WarehouseName = inv.WarehouseName,
                        AreaName = inv.AreaName,
                        LocationCode = inv.LocationCode,
                        MaterialId = inv.MaterialId,
                        MaterialCode = inv.MaterialCode,
                        MaterialName = inv.MaterialName,
                        BatchNo = inv.BatchNo,
                        SmallBatchNo = inv.SmallBatchNo,
                        StartQty = lockCell.InventoryQty,
                        ChangeQty = lockCell.OutQty,
                        EndQty = lockCell.InventoryQty - lockCell.OutQty,
                        CreateDate = DateTime.Now,
                        CreateUser = OrderDTO.CreateUser,
                        CreateUserId = OrderDTO.CreateUserld,
                        BaseUnitName = inv.UnitName,
                        OwnerId = inv.OwnerId,
                        OwnerName = inv.OwnerName,
                        AreaId = inv.AreaId,
                        PalletBarcode = inv.PalletBarcode,
                    };
                    Context.TInventoryLogs.Add(inventoryLog);
                    if (Context.SaveChanges() <= 0)
                    {
                        tran.Rollback();
                        errorMsg = "系统错误，库存流水添加失败";
                        return false;
                    }

                    //如果shippingOrder.Id所对应的仓位锁定表中的所有托盘全部已完成则把这条出库单改为已完成
                    var lockCellStatus = Context.TShippingLockCells.Where(s => s.OrderDetailId == shippingOrder.Id).ToList();
                    if (lockCellStatus.Any(l => l.IsPicking == false))
                    {
                        tran.Commit();
                        return true;
                    }
                    if (lockCellStatus != null && lockCellStatus.Count() > 0)
                    {
                        shippingOrder.Status = 4;
                        Context.Update(shippingOrder);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "修改出库单为复核失败";
                            return false;
                        }
                    }
                    tran.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    tran.Rollback();
                    errorMsg = ex.Message;
                    return false;
                }
            }
        }

        /// <summary>
        /// 带有移库的出库
        /// </summary>
        /// <param name="OrderDTO"></param>
        /// <param name="errorMsg"></param>
        /// <param name="isOutOver">代表全部出库完成</param>
        /// <returns></returns>
        public bool OutHouse(SubmitOutListDTONow OrderDTO, out string errorMsg, out bool isOutOver)
        {
            errorMsg = "出库成功";
            isOutOver = false;
            using (var tran = Context.Database.BeginTransaction())
            {
                try
                {
                    // 出库复核 修改出库单为复核
                    var shippingOrder = Context.TShippingOrderDetails.Find(OrderDTO.OrderDetId);
                    if (shippingOrder != null)
                    {
                        shippingOrder.IsOutOrderReview = true;
                        Context.Update(shippingOrder);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "修改出库单为复核失败";
                            return false;
                        }
                    }
                    else
                    {
                        tran.Rollback();
                        errorMsg = "出库单查询失败,出库单id:" + OrderDTO.OrderDetId;
                        return false;
                    }
                    //仓位锁定表 找到要出库的托盘
                    var lockCell = Context.TShippingLockCells.Where(s => s.OrderDetailId == shippingOrder.Id &&
                                                                    s.PalletBarcode == OrderDTO.PalletBarcode[0]).FirstOrDefault();
                    if (lockCell == null)
                    {
                        tran.Rollback();
                        errorMsg = "仓位锁定表查询失败,出库单id:" + shippingOrder.Id;
                        return false;
                    }

                    //查询托盘
                    var tuoPan = Context.TPallets.FirstOrDefault(s => s.PalletBarcode == lockCell.PalletBarcode);
                    if (tuoPan == null)
                    {
                        tran.Rollback();
                        errorMsg = "托盘查询失败,托盘条码:" + lockCell.PalletBarcode;
                        return false;
                    }
                    if (tuoPan.Status == 0)
                    {
                        tran.Rollback();
                        errorMsg = "托盘已被禁用,托盘条码:" + lockCell.PalletBarcode;
                        return false;
                    }

                    //库存记录
                    var inv = Context.TInventories.Where(s => s.PalletBarcode == lockCell.PalletBarcode).FirstOrDefault();
                    if (inv == null)
                    {
                        tran.Rollback();
                        errorMsg = "库存查询失败,托盘：" + lockCell.PalletBarcode;
                        return false;
                    }
                    //找出库存表中的对应仓位对象
                    var cellByInv = tCell.GetAll().FirstOrDefault(s => s.Code == inv.LocationCode);
                    if (cellByInv == null)
                    {
                        tran.Rollback();
                        errorMsg = "库存中的仓位数据，仓位查询失败,仓位编码：" + inv.LocationCode;
                        return false;
                    }
                    //如果仓位不是离巷道最近的就有可能要移库
                    if (cellByInv.DepthIndex != 0)
                    {
                        //获取出库仓位的同一组仓位
                        var broCell = tCell.GetCellByCell(new List<TCell>() { cellByInv });
                        if (broCell == null || broCell.Count() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "出库仓位的同组仓位查询失败,仓位编码：" + cellByInv.Code;
                            return false;
                        }
                        //找出出库仓位前面的仓位
                        broCell = broCell.Where(s => s.DepthIndex < cellByInv.DepthIndex).ToList();
                        //获取根据同组仓位的库存数据
                        var invByBroCell = new List<TInventory>();
                        if (broCell != null && broCell.Count() >= 0)
                        {
                            invByBroCell = Context.TInventories.AsEnumerable().Where(s => broCell.Any(c => c.Code == s.LocationCode)).ToList();
                        }
                        if (invByBroCell != null && invByBroCell.Count() >= 0)
                        {
                            //找出同组仓位中不是同物料同批次的库存
                            var noBacthAndMaterInv = invByBroCell.Where(s => s.MaterialCode != inv.MaterialCode && s.BatchNo != inv.BatchNo);
                            //如果同组仓位中有和本次出库物料和批次不一致的，则把挡住的物料进行移库
                            if (noBacthAndMaterInv != null && noBacthAndMaterInv.Count() >= 0)
                            {

                                //开始下移库单
                                List<string> moveOrderSnList = new List<string>();
                                foreach (var item in noBacthAndMaterInv)
                                {
                                    //移库单号
                                    var moveOrderSn = CreateOrderID(OperationEnum.Remove);
                                    TTransferBinOrder transferBin = new TTransferBinOrder()
                                    {
                                        OrderSn = moveOrderSn,

                                        BillType = 1,

                                    };
                                    InsertTransferBinOrder(transferBin, out var moverrorMsg);
                                }





                                tran.Rollback();
                                errorMsg = "仓位前有遮挡物料,已下移库单,请执行移库单！移库单号：" + string.Join(',', moveOrderSnList);
                                return false;
                            }
                        }
                    }


                    //库存数量大于出库数量 则减去库存数量
                    if (inv.AvailableQty > lockCell.OutQty)
                    {
                        inv.AvailableQty -= lockCell.OutQty;
                        inv.OutQty += lockCell.OutQty;
                        inv.PickedQty += lockCell.OutQty;
                        //inv.Status = 1;
                        //如果托盘上还有物料了 则把托盘再次进行入库
                        Context.Update(inv);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，库存数量修改失败";
                            return false;
                        }
                        //添加入库单
                        var tROrder = new TReceivingOrderDetail()
                        {
                            AreaCode = inv.AreaCode,
                            AreaName = inv.AreaName,
                            BatchNo = inv.BatchNo,
                            SmallBatchNo = inv.SmallBatchNo,
                            CreateDate = DateTime.Now,
                            InStarDate = DateTime.Now,
                            MaterialCode = inv.MaterialCode,
                            MaterialId = inv.MaterialId,
                            MaterialName = inv.MaterialName,
                            MaterialKeyId = inv.MaterialKeyId,
                            WarehouseCode = inv.WarehouseCode,
                            WarehouseId = inv.WarehouseId,
                            WarehouseName = inv.WarehouseName,
                            OwnerId = inv.OwnerId,
                            OwnerName = inv.OwnerName,
                            SupplierId = inv.SupplierId,
                            SupplierName = inv.SupplierName,
                            UnitId = inv.UnitId,
                            UnitName = inv.UnitName,
                            Qty = inv.AvailableQty,
                            ReceivedQty = 0,
                            StackedQty = inv.AvailableQty,
                            SourceType = 4,
                            OrderSn = barCodeRuleRepository.GetBarCodeSample(1),
                            QualityState = 1,
                            Status = 3,
                            PackagedQty = 0,
                            PackQty = 0,
                            BatchNoExplain = inv.BatchNoExplain,
                            OutFactoryDate = inv.OutFactoryDate,
                            ProduceFactory = inv.ProduceFactory,
                            ExpireDate = inv.ExpireDate,
                            Remark = inv.Remark,
                            BillType = 1,
                            CreateUserId = OrderDTO.CreateUserld,
                            CreateUserName = OrderDTO.CreateUser,
                            PalletBarcode = inv.PalletBarcode
                        };
                        Context.TReceivingOrderDetails.Add(tROrder);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，入库单添加失败";
                            return false;
                        }
                        Context.TLogs.Add(new TLog()
                        {
                            ActionType = 4,
                            CreateDate = DateTime.Now,
                            Description = $"出库时托盘没出完,{inv.PalletBarcode}进行了回流入库，操作人{OrderDTO.CreateUser}",
                            LogType = 1,
                            ModuleName = "PDA出库",
                            UserId = OrderDTO.CreateUserld,
                            UserName = OrderDTO.CreateUser,
                        });
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，回流入库日志添加失败";
                            return false;
                        }
                        //找出组跺记录
                        var tStackingStorage = Context.TStackingStorages.FirstOrDefault(s => s.PalletBarcode == inv.PalletBarcode && s.Status == 1);
                        if (tStackingStorage == null)
                        {
                            tran.Rollback();
                            errorMsg = "找不到组跺记录，托盘条码：" + inv.PalletBarcode;
                            return false;
                        }
                        //修改指令表的入库单id 这里放在上面是因为要根据组跺表的出库单id修改之前进行查询
                        var Instructobj = Context.TInstructs.FirstOrDefault(i => i.RelatedOrderDetailId == tStackingStorage.RelatedOrderDetailId);
                        if (Instructobj == null)
                        {
                            tran.Rollback();
                            errorMsg = "找不到入库指令，入库单id：" + tStackingStorage.RelatedOrderDetailId;
                            return false;
                        }

                        //找出站台
                        var station = Context.TStations.FirstOrDefault(r => r.WhId == tROrder.WarehouseId);
                        if (station == null)
                        {
                            tran.Rollback();
                            errorMsg = "请配置站台,仓库id:" + tROrder.WarehouseId;
                            return false;
                        }
                        //入库分配仓位
                        var target = tCell.AllocateCell
                        (
                            station,
                            tROrder.MaterialId.GetValueOrDefault(),
                            tROrder.MaterialKeyId.GetValueOrDefault(),
                            tROrder.QualityState,
                            (int)EmHeightType.H1150,
                            out errorMsg,
                            tStackingStorage.LogicalPartCode
                        );
                        if (target == null)
                        {
                            tran.Rollback();
                            errorMsg = "未找到入库仓位";
                            return false;
                        }
                        //修改出库单仓位
                        tROrder.LocationCode = target.Code;
                        tROrder.LocationName = target.Name;
                        Context.Update(tROrder);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，入库单分配仓位失败";
                            return false;
                        }
                        //修改组跺表仓位
                        tStackingStorage.ExpectedLocation = target.Code;
                        tStackingStorage.Qty = inv.AllocateQty;
                        tStackingStorage.RelatedOrderDetailId = tROrder.Id;
                        Context.Update(tStackingStorage);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，组跺表修改失败";
                            return false;
                        }
                        //入库指令修改
                        Instructobj.RelatedOrderDetailId = tROrder.Id;
                        Instructobj.ExpectedToLocation = target.Code;
                        Context.Update(Instructobj);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，入库指令修改失败";
                            return false;
                        }
                        //锁仓位
                        var cell = Context.TCells.FirstOrDefault(x => x.Code == target.Code);
                        if (cell == null)
                        {
                            tran.Rollback();
                            errorMsg = "未找到仓位数据";
                            return false;
                        }
                        cell.BusinessType = (int)EmBusinessType.In;
                        cell.IsLock = true;
                        cell.FullStatus = 1;
                        cell.Status = (int)EmCellStatus.Lock;
                        cell.ModifyDate = DateTime.Now;
                        Context.TCells.Update(cell);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，锁定仓位失败";
                            return false;
                        }
                        errorMsg = "出库成功，托盘已添加到入库单";
                    }
                    //库存数量等于出库数量 删除库存
                    else if (inv.AvailableQty == lockCell.OutQty)
                    {
                        //如果托盘上没有物料了 则解绑托盘和入库跺
                        Context.Remove(inv);
                        //入库跺解绑  
                        var tStackingStorage = Context.TStackingStorages.FirstOrDefault(s => s.PalletBarcode == inv.PalletBarcode && s.Status == 1);
                        if (tStackingStorage == null)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，托盘查询不到";
                            return false;
                        }
                        tStackingStorage.Status = 0;
                        Context.Update(tStackingStorage);
                        //托盘解绑
                        var tPalletBarCode = Context.TPallets.FirstOrDefault(s => s.PalletBarcode == inv.PalletBarcode);
                        if (tPalletBarCode == null)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，托盘查询不到";
                            return false;
                        }
                        tPalletBarCode.WarehouseId = 0;
                        tPalletBarCode.LocationCode = null;
                        tPalletBarCode.LocationName = null;
                        tPalletBarCode.ErplocationName = null;
                        tPalletBarCode.ModifyDate = null;
                        Context.Update(tPalletBarCode);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "系统错误，托盘解绑失败";
                            return false;
                        }
                    }
                    else
                    {
                        tran.Rollback();
                        errorMsg = "出库数量有误,出库数量不能大于托盘剩余数量";
                        return false;
                    }
                    lockCell.IsPicking = true;
                    Context.Update(lockCell);
                    if (Context.SaveChanges() <= 0)
                    {
                        tran.Rollback();
                        errorMsg = "系统错误，库存更改失败";
                        return false;
                    }

                    //修改仓位状态为空仓
                    var cellObj = Context.TCells.FirstOrDefault(s => s.Code == lockCell.CellCode);
                    if (cellObj == null)
                    {
                        tran.Rollback();
                        errorMsg = "仓位寻找失败";
                        return false;
                    }
                    cellObj.FullStatus = 0;
                    Context.Update(cellObj);
                    if (Context.SaveChanges() <= 0)
                    {
                        tran.Rollback();
                        errorMsg = "系统错误，仓位状态修改失败";
                        return false;
                    }


                    //库存流水添加
                    TInventoryLog inventoryLog = new TInventoryLog()
                    {
                        SourceType = 1,
                        SourceSn = shippingOrder.OrderSn,
                        WarehouseId = inv.WarehouseId,
                        WarehouseName = inv.WarehouseName,
                        AreaName = inv.AreaName,
                        LocationCode = inv.LocationCode,
                        MaterialId = inv.MaterialId,
                        MaterialCode = inv.MaterialCode,
                        MaterialName = inv.MaterialName,
                        BatchNo = inv.BatchNo,
                        SmallBatchNo = inv.SmallBatchNo,
                        StartQty = lockCell.InventoryQty,
                        ChangeQty = lockCell.OutQty,
                        EndQty = lockCell.InventoryQty - lockCell.OutQty,
                        CreateDate = DateTime.Now,
                        CreateUser = OrderDTO.CreateUser,
                        CreateUserId = OrderDTO.CreateUserld,
                        BaseUnitName = inv.UnitName,
                        OwnerId = inv.OwnerId,
                        OwnerName = inv.OwnerName,
                        AreaId = inv.AreaId,
                        PalletBarcode = inv.PalletBarcode,
                    };
                    Context.TInventoryLogs.Add(inventoryLog);
                    if (Context.SaveChanges() <= 0)
                    {
                        tran.Rollback();
                        errorMsg = "系统错误，库存流水添加失败";
                        return false;
                    }

                    //如果shippingOrder.Id所对应的仓位锁定表中的所有托盘全部已完成则把这条出库单改为已完成
                    var lockCellStatus = Context.TShippingLockCells.Where(s => s.OrderDetailId == shippingOrder.Id).ToList();
                    if (lockCellStatus.Any(l => l.IsPicking == false))
                    {
                        tran.Commit();
                        return true;
                    }
                    if (lockCellStatus != null && lockCellStatus.Count() > 0)
                    {
                        shippingOrder.Status = 4;
                        Context.Update(shippingOrder);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "修改出库单为复核失败";
                            return false;
                        }
                    }
                    tran.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    tran.Rollback();
                    errorMsg = "catch:" + ex.Message;
                    return false;
                }
            }
        }


        /// <summary>
        /// 生成移库单号
        /// </summary>
        /// <param name="operationEnum"></param>
        /// <returns></returns>
        private string CreateOrderID(OperationEnum operationEnum)
        {
            //去并发
            Random rnd = new Random(Guid.NewGuid().GetHashCode());
            int randNum = rnd.Next(1, 10000);
            //去重 
            string str = DateTime.Now.ToString("yyyyMMddHHmmssfff") + randNum.ToString("0000");
            switch (operationEnum)
            {
                case OperationEnum.Out:
                    return "O" + str;

                case OperationEnum.In:
                    return "I" + str;
                case OperationEnum.Remove:
                    return "M" + str;
                default:
                    return str;
            }

        }

        /// <summary>
        /// 添加移库单
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private bool InsertTransferBinOrder(TTransferBinOrder model, out string errorMsg)
        {
            errorMsg = string.Empty;
            bool result = false;
            using var tran = Context.Database.BeginTransaction();
            try
            {
                model.CreateDate = DateTime.Now;
                Context.Add(model);
                var addRes = Context.SaveChanges();
                if (addRes <= 0)
                {
                    errorMsg = "添加移库单失败";
                    tran.Rollback();
                    return false;
                }

                // 创建日志模型对象
                TLog logModel = new TLog
                {
                    LogType = (int)EmDbLogType.Operate,
                    ActionType = (int)EmLogAction.Create,
                    RecordType = (int)EmFuncRecordType.MoveOrder,
                    RecordId = model.Id,
                    Status = 1,
                    CreateDate = model.CreateDate,
                    UserId = model.CreateUserId,
                    UserName = model.CreateUserName,
                    RealName = model.CreateUserName,
                    ModuleName = "移库单",
                    Description = model.CreateUserName + "创建了移库单" + model.OrderSn
                };

                // 调用InsertLog方法
                Context.Add(logModel);
                result = Context.SaveChanges() > 0 ? true : false;

                if (model.OrderDetailList != null && model.OrderDetailList.Count > 0)
                {
                    foreach (TTransferBinOrderDetail item in model.OrderDetailList)
                    {
                        item.OrderId = model.Id;
                        item.OrderSn = model.OrderSn;
                        item.CreateUserId = model.CreateUserId;
                        item.CreateUserName = model.CreateUserName;
                        item.CreateDate = model.CreateDate;
                        item.ModifyUserId = model.ModifyUserId;
                        item.ModifyUserName = model.ModifyUserName;
                        item.ModifyDate = model.ModifyDate;
                        Context.Add(item);
                        result = result && Context.SaveChanges() > 0 ? true : false;
                    }
                }

                if (result)
                {
                    tran.Commit();
                    return true;
                }
                else
                {
                    errorMsg = "添加失败";
                    tran.Rollback();
                    return false;
                }
            }
            catch (Exception ex)
            {
                errorMsg = "catch:" + ex.Message;
                tran.Rollback();
                return false;
            }


        }


    }
}
